查看原文
其他

Libsvm学习心得

杨洋,崔光彬 主观认知下降 2022-04-16

快,关注这个公众号,一起涨姿势~

最近遇到一些数据分析问题要用到SVM,而之前介绍过的WEKA软件不能满足需求,所以开始研究libsvm程序包。(首先声明,我是刚开始学习,以下内容是学习过程的总结,希望可以和大家分享和探讨,有不对的地方欢迎指出。)

LibSVM是台湾林智仁(Chih-Jen Lin)教授2001年开发的一套支持向量机的库,这套库运算速度还是挺快的,可以很方便的对数据做分类或回归。由于libSVM程序小,运用灵活,输入参数少,并且是开源的,易于扩展,因此成为目前国内应用最多的SVM的库。下载网址:http://www.csie.ntu.edu.tw/~cjlin/

问题一

第一个遇到的问题是在Matlab中安装。Windows系统的话就不用说了,很简单,下载后setpath即可。而对于Mac系统则颇费周折,详细的安装指南可以参考:http://www.jianshu.com/p/e0275a380803

经本人测试可以顺利安装。


问题二

第二个则是libsvm函数与Matlab自带SVM函数冲突。我们知道,Matlab本身是有svmtrain函数的,该函数与libsvm相比存在以下几个差别:


1.     自带函数仅有C-SVC模型,而libsvm工具箱有C-SVC(C-support vector classification),nu-SVC(nu-support vector classification),one-class SVM(distribution estimation),epsilon-SVR(epsilon-support vector regression),nu-SVR(nu-support vector regression)等多种模型可供使用。


2.     自带函数仅支持分类问题,libsvm支持分类和回归问题。


3.     自带函数只是针对二分类问题,多分类问题需按照多分类的相应算法编程实现;而libsvm采用1v1算法支持多分类。


4.     自带函数采用RBF核函数时无法调节核函数的参数gamma,貌似仅能用默认的;而libsvm可以进行该参数的调节。

 

如果安装好libsvm后直接调用svmtrain(),用的还是MATLAB自带的函数。解决方法如下:

libsvm指南学习


准备就绪后,接下来便是学习libsvm包中的Guide文件,受益匪浅。简单总结几个Tips如下:


1.     操作步骤:一般初学者的操作步骤是:数据转换成SVM包要求的形式;随机尝试一些kernel和参数;测试。而指南推荐的步骤是:数据转换成SVM包要求的形式;进行简单的scale;推荐RBF kernel;通过交叉验证找到最佳参数值(C和gamma);使用得到的最佳参数训练整个训练集;测试。


2.     对于多分类问题,例如三分类,推荐使用(0,0,1),(0,1,0)和(1,0,0)来表示label。文中解释是因为,当一个attribute的值不是很大时,这种coding的方式更稳定。


3.     关于scaling。在做SVM时,数据标准化是必不可少的,指南推荐使用线性scaling将每个attribute归一化至[-1,+1]或[0,1],包括训练集和测试集。需要注意的是,训练集和测试集最好使用相同的scale。


4.     关于RBF kernel。一般情况下是首选。在一些特殊情况时,选择linear kernel,包括:instance数远小于feature数时;instance数与feature数都很大时;instance数远大于feature数时。


5.     关于交叉验证(cross validation, CV)和格点搜索(grid-search)。因为最开始我们并不知道对于给定的问题,什么参数设置最合适,因此应该通过grid-search的方法结合交叉验证找到最优参数。一般是使用指数递增的方法寻找最优参数,例如,C = 2^-5; 2^-3; ... ; 2^15, gamma = 2^-15; 2^-13; ...; 2^3.


关于SVM多分类问题的补充


目前,构造SVM多类分类器的方法主要有两类:一类是直接法,直接在目标函数上进行修改,将多个分类面的参数求解合并到一个最优化问题中,通过求解该最优化问题“一次性”实现多类分类。这种方法看似简单,但其计算复杂度比较高,实现起来比较困难,只适合用于小型问题中;另一类是间接法,主要是通过组合多个二分类器来实现多分类器的构造,常见的方法有one-against-one和one-against-all两种。


a.一对多法(one-versus-rest,简称OVR SVMs)。训练时依次把某个类别的样本归为一类,其他剩余的样本归为另一类,这样k个类别的样本就构造出了k个SVM。分类时将未知样本分类为具有最大分类函数值的那类。

 

假如我有四类要划分(也就是4个Label),他们是A、B、C、D。于是我在抽取训练集的时候,分别抽取A所对应的向量作为正集,B,C,D所对应的向量作为负集;B所对应的向量作为正集,A,C,D所对应的向量作为负集;C所对应的向量作为正集, A,B,D所对应的向量作为负集;D所对应的向量作为正集,A,B,C所对应的向量作为负集,这四个训练集分别进行训练,然后的得到四个训练结果文件,在测试的时候,把对应的测试向量分别利用这四个训练结果文件进行测试,最后每个测试都有一个结果f1(x),f2(x),f3(x),f4(x).于是最终的结果便是这四个值中最大的一个。

 

note:这种方法有种缺陷,因为训练集是1:M,这种情况下存在biased.因而不是很实用.

 

b.一对一法(one-versus-one,简称OVO SVMs或者pairwise)。其做法是在任意两类样本之间设计一个SVM,因此k个类别的样本就需要设计k(k-1)/2个SVM。当对一个未知样本进行分类时,最后得票最多的类别即为该未知样本的类别。Libsvm中的多类分类就是根据这个方法实现的。

 

还是假设有四类A,B,C,D四类。在训练的时候我选择A,B; A,C; A,D; B,C; B,D;C,D所对应的向量作为训练集,然后得到六个训练结果,在测试的时候,把对应的向量分别对六个结果进行测试,然后采取投票形式,最后得到一组结果。

 

投票是这样的.

A=B=C=D=0;

(A, B)-classifier 如果是A win,则A=A+1;otherwise,B=B+1;

(A,C)-classifer 如果是A win,则A=A+1;otherwise, C=C+1;

...

(C,D)-classifer 如果是A win,则C=C+1;otherwise,D=D+1;

The decision is the Max(A,B,C,D)

 

note:这种方法虽然好,但是当类别很多的时候, model的个数是n*(n-1)/2,代价还是相当大的.

 

c.层次支持向量机(H-SVMs)。层次分类法首先将所有类别分成两个子类,再将子类进一步划分成两个次级子类,如此循环,直到得到一个单独的类别为止。


在此,感谢西安电子科技大学焦志成博士、西北工业大学夏勇教授和谢雨桐博士、第四军医大学张曦讲师、第四军医大学唐都医院张欣博士对我这段时间的指导和帮助。

父母的世界很小,只装满了我们。我们的世界很大,常忽略了他们。他们经常忘了我们已经长大,就像我们经常忘了他们,已经渐渐白发。这个世界上,再也没有任何人,可以像父母一样,爱我们如生命。 愿天下所有的父亲,父亲节日快乐、健康长寿!

长|按|二|维|码|关|注

往期精彩内容:

  1.  胎儿可以做磁共振吗?

  2. 做CT检查还是MRI检查?

  3. 从电影中学习优雅的老去

  4. 多模态磁共振脑影像数据库盘点之脑疾病数据库

  5. 人工智能(AI)分析MRI数据,可以预测婴儿自闭症啦!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存